package aliyun

import (
	"gitee.com/saxon134/sysmain/db"
	"gitee.com/saxon134/sysmain/db/models"
	"gitee.com/saxon134/sysmain/errs"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
	"github.com/saxon134/go-utils/saData/saHit"
	"github.com/saxon134/go-utils/saData/saTime"
	"github.com/saxon134/go-utils/saLog"
	"github.com/saxon134/go-utils/saOrm"
	"strings"
	"time"
)

type client struct {
	region       string
	accessKey    string
	accessSecret string
}

var _client *client
var _ecsClient *ecs.Client

func Init(region string, accessKey string, accessSecret string) {
	if region == "" || accessKey == "" || accessSecret == "" {
		saLog.Err("Leak params for aliyun")
		return
	}

	_client = &client{
		region:       region,
		accessKey:    accessKey,
		accessSecret: accessSecret,
	}

	var err error
	_ecsClient, err = ecs.NewClientWithAccessKey(_client.region, _client.accessKey, _client.accessSecret)
	if err != nil {
		saLog.Err(errs.New(err))
		_ecsClient = nil
		_client = nil
	}
}

// SyncAliYunEcsList 同步阿里云ECS信息
func SyncAliYunEcsList() (err error) {
	if _client == nil {
		return errs.New("aliyun未配置")
	}

	var response *ecs.DescribeInstancesResponse
	response, err = _ecsClient.DescribeInstances(&ecs.DescribeInstancesRequest{})
	if err != nil {
		return errs.New(err)
	}

	if len(response.Instances.Instance) == 0 {
		return nil
	}

	var ecsAry = make([]*models.TblResource, 0, 10)
	err = db.MySql.Table(models.TBNResource).Where("`type` = 1").Find(&ecsAry).Error
	if db.MySql.IsError(err) {
		return errs.New(err)
	}

	var existedAry = make([]*models.TblResource, 0, len(response.Instances.Instance))
	var InstanceIds = make([]string, 0, len(response.Instances.Instance))
	{
		for _, v := range response.Instances.Instance {
			InstanceIds = append(InstanceIds, v.InstanceId)
		}
		if len(InstanceIds) > 0 {
			err = db.MySql.Table(models.TBNResource).
				Select("id", "instance_id").
				Where("instance_id in ?", InstanceIds).
				Find(&existedAry).Error
			if db.MySql.IsError(err) {
				return errs.New(err)
			}
		}
	}

	var addAry = make([]*models.TblResource, 0, len(response.Instances.Instance))
	var updateAry = make([]*models.TblResource, 0, len(response.Instances.Instance))
	for _, v := range response.Instances.Instance {
		var m = &models.TblResource{
			Id:         0,
			CreateAt:   nil,
			InstanceId: v.InstanceId,
			Type:       1,
			Status:     saHit.Int(v.Status == "Running", 2, 10),
			Name:       v.InstanceName,
			Cpu:        v.CPU,
			Memo:       v.Memory,
			PublicIp:   strings.Join(v.PublicIpAddress.IpAddress, ","),
			InnerIp:    strings.Join(v.InnerIpAddress.IpAddress, ","),
		}

		m.Config = saOrm.Dic{
			"cpu": map[string]interface{}{
				"Numa":           v.CpuOptions.Numa,           //分配的线程数
				"CoreCount":      v.CpuOptions.CoreCount,      //物理CPU核心数
				"ThreadsPerCore": v.CpuOptions.ThreadsPerCore, //CPU线程数
			},
		}

		var existed = false
		for _, e := range existedAry {
			if e.InstanceId == m.InstanceId {
				m.Id = e.Id
				updateAry = append(updateAry, m)
				existed = true
				break
			}
		}

		if existed == false {
			addAry = append(addAry, m)
		}
	}

	if len(addAry) > 0 {
		err = db.MySql.Table(models.TBNResource).Save(addAry).Error
		if err != nil {
			return errs.New(err)
		}
	}

	if len(updateAry) > 0 {
		err = db.MySql.Table(models.TBNResource).Save(updateAry).Error
		if err != nil {
			return errs.New(err)
		}
	}

	return nil
}

func SyncAliYunEcsMonitorData(instanceId string) (monitor saOrm.Dic, err error) {
	if _client == nil {
		return nil, errs.New("aliyun未配置")
	}

	var now = time.Now()
	var response *ecs.DescribeInstanceMonitorDataResponse
	response, err = _ecsClient.DescribeInstanceMonitorData(&ecs.DescribeInstanceMonitorDataRequest{
		StartTime:  saTime.TimeToStr(now.Add(time.Second*-600), saTime.FormatSystem),
		EndTime:    saTime.TimeToStr(now, saTime.FormatSystem),
		Period:     "600",
		InstanceId: instanceId,
	})
	if err != nil {
		return
	}

	if len(response.MonitorData.InstanceMonitorData) == 0 {
		return
	}

	var data = response.MonitorData.InstanceMonitorData[0]
	monitor = saOrm.Dic{
		"BPSRead":    data.BPSRead,    //实例云盘（包括系统盘和数据盘）的读带宽，单位：Byte/s
		"BPSWrite":   data.BPSWrite,   //实例云盘（包括系统盘和数据盘）的写带宽，单位：Byte/s
		"InternetTX": data.InternetTX, //公网数据发送流量，单位：kbits
		"InternetRX": data.InternetRX, //公网数据接收流量，单位：kbits
		"IntranetTX": data.IntranetTX, //内网数据发送流量，单位：kbits
		"IntranetRX": data.IntranetRX, //内网数据接收流量，单位：kbits
		"CPU":        data.CPU,        //实例vCPU的使用比例，单位：百分比（%）
		"IOPSWrite":  data.IOPSWrite,  //实例云盘（包括系统盘和数据盘）的I/O写操作，单位：次/s
		"IOPSRead":   data.IOPSRead,   //实例云盘（包括系统盘和数据盘）的I/O读操作，单位：次/s
		"TimeStamp":  saTime.TimeToStr(saTime.TimeFromStr(data.TimeStamp, saTime.FormatSystem), saTime.FormatDefault),
	}

	err = db.MySql.Table(models.TBNResource).
		Where("instance_id = ?", instanceId).Where("`type` = 1").
		Update("monitor", monitor).Error
	if db.MySql.IsError(err) {
		saLog.Err(errs.New(err))
	}

	return monitor, nil
}
